From: Florian Müllner Date: Wed, 12 Jul 2023 23:52:06 +0000 (+0200) Subject: jsParse: Make getCompletions() asynchronous X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~337^2~1^2~149 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=c0fbd74d0709861c5f695769a30d06a284449802;p=gnome-shell.git jsParse: Make getCompletions() asynchronous Part of the possible completions involves evaluating the part of the passed in text that looks like an object, so that we can query it for properties. Using a Function or eval() for that means that we can only complete text that does not use `await`. To get over that limitation, evaluate the text in an AsyncFunction instead. Part-of: --- diff --git a/js/misc/jsParse.js b/js/misc/jsParse.js index 18ce70398..e55d69a30 100644 --- a/js/misc/jsParse.js +++ b/js/misc/jsParse.js @@ -1,6 +1,8 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ /* exported getCompletions, getCommonPrefix, getDeclaredConstants */ +const AsyncFunction = async function () {}.constructor; + /** * Returns a list of potential completions for text. Completions either * follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo) @@ -13,7 +15,7 @@ * @param {string} commandHeader * @param {readonly string[]} [globalCompletionList] */ -function getCompletions(text, commandHeader, globalCompletionList) { +async function getCompletions(text, commandHeader, globalCompletionList) { let methods = []; let expr_, base; let attrHead = ''; @@ -29,7 +31,7 @@ function getCompletions(text, commandHeader, globalCompletionList) { if (matches) { [expr_, base, attrHead] = matches; - methods = getPropertyNamesFromExpression(base, commandHeader).filter( + methods = (await getPropertyNamesFromExpression(base, commandHeader)).filter( attr => attr.slice(0, attrHead.length) === attrHead); } @@ -193,13 +195,13 @@ function getAllProps(obj) { * @param {string} expr * @param {string=} commandHeader */ -function getPropertyNamesFromExpression(expr, commandHeader = '') { +async function getPropertyNamesFromExpression(expr, commandHeader = '') { let obj = {}; if (!isUnsafeExpression(expr)) { try { - const lines = expr.split(';'); + const lines = expr.split('\n'); lines.push(`return ${lines.pop()}`); - obj = Function(commandHeader + lines.join(';'))(); + obj = await AsyncFunction(commandHeader + lines.join(';'))(); } catch (e) { return []; }